#include "stdafx.h"
#include "UTextureManager.h"
#include "UStringUtils.h"
#include <SDL/SDL_image.h>
#include <GL/glu.h>
#include <iostream>
using namespace std;

#define TEXTURE_BASE_PATH "Data/Textures/"

TTextureManager* GTextureManager = new TTextureManager();

TTextureManager::TTextureManager() {
}

TTextureManager::~TTextureManager() {
}

SDL_Surface* TTextureManager::LoadImage(std::string filename) {
	return IMG_Load( filename.c_str() );
}

int nextPowerOfTwo(int arg)
{
	int x = 1;
	while (x < arg) x <<= 1;
	return x;
}

GLuint TTextureManager::getTexture(std::string texturename, bool isFullPath, uint32 MinFilter, uint32 MagFilter, bool powerof2) {
	GLuint texture = GL_ZERO;
	if(texturemap.count(texturename) > 0) {
		texture = texturemap[texturename];
	}
	else {
		SDL_Surface *textureImage;
		if(isFullPath) {
			textureImage = IMG_Load( (texturename).c_str() );
		}
		else {
			textureImage = IMG_Load( (TEXTURE_BASE_PATH + texturename).c_str() );
		}
		if (textureImage && powerof2) {
			SDL_Surface* tempImage;
			int nw = nextPowerOfTwo(textureImage->w);
			int nh = nextPowerOfTwo(textureImage->h);
			tempImage = SDL_CreateRGBSurface(textureImage->flags,
			                                 nw,
			                                 nh,
			                                 32,
			                                 0x000000ff,
			                                 0x0000ff00,
			                                 0x00ff0000,
			                                 0xff000000
			                                 );
			SDL_Rect rect;
			rect.x = 0;  rect.y = 0;
			rect.w = nw; rect.h = nw;

			int res;
			res = SDL_FillRect(tempImage,
			                   &rect,
			                   //SDL_MapRGBA(tempImage->format, 0,0,0, 0));
			                   0);

			SDL_SetAlpha(textureImage, 0, 0);
			res = SDL_BlitSurface(textureImage, NULL, tempImage, NULL);
			SDL_FreeSurface(textureImage);
			textureImage = tempImage;
		}
		if(textureImage) {
			glGenTextures(1, &texture);
			glBindTexture(GL_TEXTURE_2D, texture);
			glTexImage2D(GL_TEXTURE_2D, 0, 4, textureImage->w, textureImage->h, 0,\
			             textureImage->format->BytesPerPixel==3?GL_RGB:GL_RGBA, GL_UNSIGNED_BYTE, textureImage->pixels);
			//FIXME: What does this do if parameters are set to NON-MipMapped ?
			//if (MinFilter != GL_LINEAR)
			gluBuild2DMipmaps(GL_TEXTURE_2D,
			                  textureImage->format->BytesPerPixel==3?GL_RGB:GL_RGBA,
			                  textureImage->w,
			                  textureImage->h,
			                  textureImage->format->BytesPerPixel==3?GL_RGB:GL_RGBA,
			                  GL_UNSIGNED_BYTE,
			                  textureImage->pixels
			                 );
			texturemap[texturename] = texture;
			SDL_FreeSurface(textureImage);
//			cerr << STRFORMAT("UTextureManager.cpp: '%s' is an image I can load!\n", texturename.c_str());
		}
		else {
			cerr << STRFORMAT("UTextureManager.cpp: '%s' is not an image I can load!\n", texturename);
			texturemap[texturename] = GL_ZERO;
			return GL_ZERO;
		}
	}
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MagFilter);
	return texture;
}

